package com.feihong.yw189.activity.pay;

import android.os.Bundle;
import android.widget.Toast;

import com.blankj.utilcode.util.LogUtils;
import com.feihong.yw189.activity.base.BaseActivity;
import com.feihong.yw189.app.App;
import com.feihong.yw189.message.LoginMessage;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tsy.sdk.pay.weixin.WXPay;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;

import java.io.StringWriter;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * @author wangziheng
 * @name Android
 * @class name：com.fhdz.ywydt.activity.pay
 * @class describe:
 * @time 2018/1/10 12:22
 * @change
 * @chang time
 * @class describe
 */
public class PayActivity extends BaseActivity {
    private static final String TAG = "营维189";

    /**
     * 测试支付参数
     */

    @Override
    public void onUserLogin(LoginMessage loginMessage) {
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        IWXAPI api = null;

//        PayReq request = new PayReq();
//
//        request.appId = "wx2f0d2647197c2d89";
//
//        request.partnerId = "1499189942";
//
//        request.prepayId = "wx20180110123849afbe55dfc00168332130";
//
//        request.packageValue = "Sign=WXPay";
//
//        request.nonceStr = "NIwpt7Q74sbQs0yntqUkiophSNonqv2E";
//
//        request.timeStamp = "1519451737";
//
//        request.sign = "7FFECB600D7157C5AA49810D2D8F28BC2811827B";
//
//        api.sendReq(request);

        Map<String, String> mPar = new HashMap<>();
        mPar.put("appId", "wx2f0d2647197c2d89");
        mPar.put("partnerId", "1499189942");
        mPar.put("prepayId", "wx20180110123849afbe55dfc00168332130");
        mPar.put("packageValue", "Sign=WXPay");
        mPar.put("nonceStr", "NIwpt7Q74sbQs0yntqUkiophSNonqv2E");
        mPar.put("timeStamp", "wx2f0d2647197c2d89");
        mPar.put("appId", "1519451737");
        try {
            String params = generateSignedXml(mPar, "");
            doPay(params);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void setTheme() {

    }

    /**
     * 服务端返回的支付参数
     *
     * @param payParasms
     */
    private void doPay(String payParasms) {

        LogUtils.i(TAG + ":kaishi");
        WXPay.init(getApplicationContext(), App.WECHAT_PAY_APPID);
        WXPay.getInstance().doPay(payParasms, new WXPay.WXPayResultCallBack() {
            @Override
            public void onSuccess() {
                LogUtils.i(TAG + "支付成功");
            }


            @Override
            public void onError(int error_code) {
                switch (error_code) {
                    case WXPay.NO_OR_LOW_WX:
                        LogUtils.i(TAG + "未安装微信或微信版本过低");
                        Toast.makeText(getApplication(), "未安装微信或微信版本过低", Toast.LENGTH_SHORT).show();
                        break;
                    case WXPay.ERROR_PAY_PARAM:
                        LogUtils.i(TAG + "支付失败");
                        Toast.makeText(getApplication(), "支付失败", Toast.LENGTH_SHORT).show();
                        break;

                    case WXPay.ERROR_PAY:
                        LogUtils.i(TAG + "支付失败");
                        Toast.makeText(getApplication(), "支付失败", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onCancel() {
                Toast.makeText(getApplication(), "支付取消", Toast.LENGTH_SHORT).show();
            }
        });
    }

    public static String generateSignedXml(final Map<String, String> data, String key) throws Exception {
        return generateSignedXml(data, key, SignType.MD5);
    }

    /**
     * 生成带有 sign 的 XML 格式字符串
     *
     * @param data Map类型数据
     * @param key API密钥
     * @param signType 签名类型
     * @return 含有sign字段的XML
     */

    public static final String FIELD_SIGN = "sign";

    public static String generateSignedXml(final Map<String, String> data, String key, SignType signType) throws Exception {
        String sign = generateSignature(data, key, signType);
        data.put(FIELD_SIGN, sign);
        return mapToXml(data);
    }

    /**
     * 将Map转换为XML格式的字符串
     *
     * @param data Map类型数据
     * @return XML格式的字符串
     * @throws Exception
     */
    public static String mapToXml(Map<String, String> data) throws Exception {
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        org.w3c.dom.Document document = documentBuilder.newDocument();
        org.w3c.dom.Element root = document.createElement("xml");
        document.appendChild(root);
        for (String key : data.keySet()) {
            String value = data.get(key);
            if (value == null) {
                value = "";
            }
            value = value.trim();
            org.w3c.dom.Element filed = document.createElement(key);
            filed.appendChild(document.createTextNode(value));
            root.appendChild(filed);
        }
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        DOMSource source = new DOMSource(document);
        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        StringWriter writer = new StringWriter();
        StreamResult result = new StreamResult(writer);
        transformer.transform(source, result);
        String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
        try {
            writer.close();
        } catch (Exception ex) {
        }
        return output;
    }

    /**
     * 生成签名
     *
     * @param data 待签名数据
     * @param key  API密钥
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key) throws Exception {
        return generateSignature(data, key, SignType.MD5);
    }

    /**
     * 生成签名. 注意，若含有sign_type字段，必须和signType参数保持一致。
     *
     * @param data     待签名数据
     * @param key      API密钥
     * @param signType 签名方式
     * @return 签名
     */
    public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception {
        Set<String> keySet = data.keySet();
        String[] keyArray = keySet.toArray(new String[keySet.size()]);
        Arrays.sort(keyArray);
        StringBuilder sb = new StringBuilder();
        for (String k : keyArray) {
            if (k.equals(FIELD_SIGN)) {
                continue;
            }
            if (data.get(k).trim().length() > 0) // 参数值为空，则不参与签名
                sb.append(k).append("=").append(data.get(k).trim()).append("&");
        }
        sb.append("key=").append(key);
        if (SignType.MD5.equals(signType)) {
            return MD5(sb.toString()).toUpperCase();
        } else if (SignType.HMACSHA256.equals(signType)) {
            return HMACSHA256(sb.toString(), key);
        } else {
            throw new Exception(String.format("Invalid sign_type: %s", signType));
        }
    }

    public enum SignType {
        MD5, HMACSHA256
    }

    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        java.security.MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }

    /**
     * 生成 HMACSHA256
     *
     * @param data 待处理数据
     * @param key  密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }
}
